/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package SVGDOM;

import java.awt.Color;
import java.awt.Point;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import svgCanvas.Rectangle.Ellipse;
import svgCanvas.Rectangle.EllipseCreator;
import svgCanvas.Rectangle.Rectangle;
import svgCanvas.Rectangle.RectangleCreator;

/**
 *
 * @author Martin
 */
public class SVGDOMManipulator {
    private static final String NAMESPACE = "http://www.w3.org/2000/svg";    
    private static final String FilterId = "i1";
    private static final String Ellipse = "Ellipse";
    private static final String Rectangle = "Rectangle";
    
    public Document AddAnnotation(Document a, Color chosenColor, String annotationText, String chosenShape, Boolean includeText, Point dragStart, Point dragEnd)
    {
        //prevents duplication of shadow filters
       if(!DoesFilterExist(a))
       {
          a = AddFilter(a);
       }
        
       if(chosenShape.equals(Rectangle))
       {
          a = AddRectangle(a, chosenColor, dragStart, dragEnd);
       }
       else if(chosenShape.equals(Ellipse))
       {
          a = AddElliplse(a, chosenColor, dragStart, dragEnd);
       }
       
       if(includeText)
       {
          a = AddTextAnnotation(a, chosenColor, annotationText, dragStart, dragEnd);
       }
       
       return a;
    }
    
    private Boolean DoesFilterExist(Document a)
    {        
        return a.getElementById(FilterId) != null;
    }
    
    private Document AddFilter(Document a)
    {
        Element root = a.getDocumentElement();
                        
        Element filter = a.createElementNS(NAMESPACE, "filter");
        filter.setAttributeNS(null, "id", FilterId);
        filter.setAttributeNS(null, "width", "300%");
        filter.setAttributeNS(null, "height", "300%");

        Element feOffset = a.createElementNS(NAMESPACE, "feOffset");
        feOffset.setAttributeNS(null, "result", "offOut");
        feOffset.setAttributeNS(null, "in", "SourceGraphic");
        feOffset.setAttributeNS(null, "dx", "20");
        feOffset.setAttributeNS(null, "dy", "20");

        Element feColorMatrix = a.createElementNS(NAMESPACE, "feColorMatrix");
        feColorMatrix.setAttributeNS(null, "result", "matrixOut");
        feColorMatrix.setAttributeNS(null, "in", "offOut");
        feColorMatrix.setAttributeNS(null, "type", "matrix");
        feColorMatrix.setAttributeNS(null, "values", "0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0");

        Element feGaussianBlur = a.createElementNS(NAMESPACE, "feGaussianBlur");
        feGaussianBlur.setAttributeNS(null, "result", "blurOut");
        feGaussianBlur.setAttributeNS(null, "in", "matrixOut");
        feGaussianBlur.setAttributeNS(null, "stdDeviation", "10");

        Element feBlend = a.createElementNS(NAMESPACE, "feBlend");
        feBlend.setAttributeNS(null, "mode", "normal");
        feBlend.setAttributeNS(null, "in", "SourceGraphic");
        feBlend.setAttributeNS(null, "in2", "blurOut");

        filter.appendChild(feOffset);
        filter.appendChild(feColorMatrix);
        filter.appendChild(feGaussianBlur);
        filter.appendChild(feBlend);

        root.appendChild(filter);
        
        return a;
    }
    
    private Document AddRectangle(Document a, Color chosenColor, Point dragStart, Point dragEnd)
    {
        Element g = a.createElementNS(NAMESPACE, "g");
        Element root = a.getDocumentElement();
        
        g.setAttributeNS(null, "filter", "url(#" + FilterId +")");

        //creates rgb string as defined for SVG document
        String svgRgbColorString = new ColorConverter().GetSvgColorStringFormat(chosenColor);

        Element rect = a.createElementNS(NAMESPACE, "rect");
        Rectangle rectangleToAdd = new RectangleCreator().CreateRectangleFromCoordinates(dragStart, dragEnd);

        //create new rectangle element and append it to the root element
        rect.setAttributeNS(null, "x", Integer.toString(rectangleToAdd.x));
        rect.setAttributeNS(null, "y", Integer.toString(rectangleToAdd.y));
        rect.setAttributeNS(null, "width", Integer.toString(rectangleToAdd.width));
        rect.setAttributeNS(null, "height", Integer.toString(rectangleToAdd.height));
        rect.setAttributeNS(null, "style", "fill:" + svgRgbColorString + ";stroke:" + svgRgbColorString + ";stroke-width:5");
        rect.setAttributeNS(null, "fill-opacity", ".1");
        g.appendChild(rect);
        root.appendChild(g);
        
        return a;
    }
    
    private Document AddTextAnnotation(Document a, Color chosenColor, String annotationText, Point dragStart, Point dragEnd)
    {
        Element root = a.getDocumentElement();
        Rectangle rectangleToAdd = new RectangleCreator().CreateRectangleFromCoordinates(dragStart, dragEnd);
        String svgRgbColorString = new ColorConverter().GetSvgColorStringFormat(chosenColor);
        
        //add a new element to the root
        Element text = a.createElementNS(NAMESPACE, "text");

        text.setAttributeNS(null, "x", Integer.toString(rectangleToAdd.x));
        text.setAttributeNS(null, "y", Integer.toString(rectangleToAdd.y - 6));
        text.setAttributeNS(null, "style", "fill:" + svgRgbColorString + ";stroke:" + svgRgbColorString + ";stroke-width:0.3");
        text.setTextContent(annotationText);

        root.appendChild(text);
        return a;
    }

    private Document AddElliplse(Document a, Color chosenColor, Point dragStart, Point dragEnd) {
        Element g = a.createElementNS(NAMESPACE, "g");
        Element root = a.getDocumentElement();
        
        g.setAttributeNS(null, "filter", "url(#" + FilterId +")");

        //creates rgb string as defined for SVG document
        String svgRgbColorString = new ColorConverter().GetSvgColorStringFormat(chosenColor);

        Element ellipseElement = a.createElementNS(NAMESPACE, "ellipse");  
        Rectangle ellipseBoundary = new RectangleCreator().CreateRectangleFromCoordinates(dragStart, dragEnd);
        Ellipse ellipse = new EllipseCreator().CreateRectangleFromCoordinates(ellipseBoundary);
        
        ellipseElement.setAttributeNS(null, "cx", Integer.toString(ellipse.cx));
        ellipseElement.setAttributeNS(null, "cy", Integer.toString(ellipse.cy));
        ellipseElement.setAttributeNS(null, "rx", Integer.toString(ellipse.rx));
        ellipseElement.setAttributeNS(null, "ry", Integer.toString(ellipse.ry));
        ellipseElement.setAttributeNS(null, "style", "fill:" + svgRgbColorString + ";stroke:" + svgRgbColorString + ";stroke-width:5");
        ellipseElement.setAttributeNS(null, "fill-opacity", ".1");
        g.appendChild(ellipseElement);
        root.appendChild(g);
        
        return a;
    }
            
    
}
